﻿using ChoMy.Constants;
using ChoMy.Models;
using ChoMy.Models.Data;
using PagedList;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.Web;
using System.Web.Mvc;

namespace ChoMy.Areas.Admin.Controllers
{
    public class OrderController : Controller
    {
        private ChoMyContext db = new ChoMyContext();

        public ActionResult Index(bool? isTrash, string search, string sortOrder, int? page, int? pageSize)
        {
            var sortList = new List<string> { "Code", "Name", "DateCreated", "PaymentStatus" };
            var pageSizeList = new List<int> { 10, 25, 50, 100 };
            int pageNumber = page ?? 1;

            pageSize = pageSize ?? 10;
            sortOrder = sortOrder ?? "DateCreated_desc";
            isTrash = isTrash ?? false;

            ViewBag.IsTrash = isTrash;
            ViewBag.PageSize = pageSize;
            ViewBag.PageSizeDDL = new SelectList(pageSizeList, pageSize);
            ViewBag.ReturnListUrl = Request.Url.AbsoluteUri;

            IQueryable<Order> query = db.Orders;

            ViewBag.TrashCount = query.Count(x => x.IsDelete);
            ViewBag.ListCount = query.Count(x => !x.IsDelete);

            if (!String.IsNullOrWhiteSpace(search))
            {
                page = 1;

                query = Search(query, search.Trim());
            }

            query = Sort(query, sortOrder, sortList);

            query = query.Where(x => x.IsDelete == isTrash);

            ViewBag.ExchangeRate = GetExchangeRate();

            return View(query.ToPagedList(pageNumber, (int)pageSize));
        }

        [HttpPost]
        public ActionResult _Details(int id)
        {
            Order model = db.Orders.Find(id);

            return View(model);
        }

        [HttpPost]
        public ActionResult Recycle(int id)
        {
            Order model = db.Orders.Find(id);

            model.IsDelete = model.IsDelete ? false : true;

            db.Entry(model).State = EntityState.Modified;
            db.SaveChanges();

            if (model.IsDelete)
            {
                SaveHistory("Recycle-Delete", model.Code);
            }
            else
            {
                SaveHistory("Recycle-Restore", model.Code);
            }

            return Json(model.IsDelete ? 1 : 0, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Delete(int id, string returnListUrl)
        {
            Order model = db.Orders.Find(id);

            string orderCode = model.Code;

            db.Orders.Remove(model);
            db.SaveChanges(); 

            SaveHistory("Delete", orderCode);
            AlertHandling("Delete", orderCode);

            if (!String.IsNullOrWhiteSpace(returnListUrl))
            {
                return Redirect(returnListUrl);
            }

            return RedirectToAction("Index", new { isTrash = true });
        }

        #region Helpers
        private void AlertHandling(string crud, string orderCode)
        {
            string userName = User.Identity.Name;
            string alertMessage = "";

            switch (crud)
            {
                case "Delete":
                    alertMessage = String.Format("Bạn vừa xóa vĩnh viễn đơn hàng: <b>{0}</b>", orderCode);
                    break;
            }

            if (!String.IsNullOrWhiteSpace(alertMessage))
            {
                Session["alert-message-" + userName] = alertMessage;
                Session["alert-type-" + userName] = "alert-success";
            }
        }

        private void SaveHistory(string crud, string orderCode)
        {
            DateTime dateTime = DateTime.Now;
            string userName = User.Identity.Name;
            string description = "";

            switch (crud)
            {
                case "Delete":
                    description = String.Format("<b>{0}</b> xóa vĩnh viễn đơn hàng <b>{1}</b>", userName, orderCode);
                    break;
                case "Recycle-Delete":
                    description = String.Format("<b>{0}</b> xóa tạm thời đơn hàng <b>{1}</b>", userName, orderCode);
                    break;
                case "Recycle-Restore":
                    description = String.Format("<b>{0}</b> khôi phục lại đơn hàng <b>{1}</b>", userName, orderCode);
                    break;
            }

            var history = new History();
            history.DateTime = dateTime;
            history.Description = description;
            history.HistoryTypeId = db.HistoryTypes.First(x => x.Name == "Order").Id;

            db.Histories.Add(history);
            db.SaveChanges();
        }

        private float GetExchangeRate()
        {
            return float.Parse(db.Settings.First(x => x.Name == "ExchangeRate").Value);
        }

        private IQueryable<Order> Search(IQueryable<Order> query, string search)
        {
            ViewBag.Search = search;

            query = query.Where(x => x.Code.Contains(search));

            return query;
        }

        private IQueryable<Order> Sort(IQueryable<Order> query, string sortOrder, List<string> sortList)
        {
            ViewBag.SortOrder = sortOrder;

            foreach (string sort in sortList)
            {
                ViewData[sort + "Sort"] = sortOrder == sort + "_desc" ? sort : sort + "_desc";
            }

            if (sortOrder.Contains("_desc"))
            {
                sortOrder = sortOrder.Replace("_desc", "");
                query = query.OrderBy(sortOrder + " descending");
                ViewData[sortOrder + "Icon"] = DataTableConstant.DescSortIcon;
            }
            else
            {
                query = query.OrderBy(sortOrder);
                ViewData[sortOrder + "Icon"] = DataTableConstant.AscSortIcon;
            }

            return query;
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }

            base.Dispose(disposing);
        }
        #endregion
    }
}